action nop() {}



/*---------- calc_digest_t ----------*/
action calc_digest_ac()
{
    modify_field_with_hash_based_offset(m_meta.digest, 0, digest_hash, 256);
}

@pragma stage 0
table calc_digest_t
{
    actions {
        calc_digest_ac;
    }
 default_action: calc_digest_ac;
}

/*---------- forward_t ----------*/
action set_egr(egress_spec) {
  modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_spec);
  /* modify_field(ipv4.dstip, 0x0a00000b); */
}

/* @pragma stage 0 */
table forward_t {
  reads {
  ig_intr_md.ingress_port: exact;
  }
  actions {
    set_egr; nop;
  }
}

/*---------- update_M1_srcip_t ----------*/
blackbox stateful_alu update_M1_srcip_bb
{
 reg: M1_srcip;
 condition_lo: register_lo == 0;
 condition_hi: register_lo == ipv4.srcip;

 update_lo_1_predicate: condition_lo or condition_hi;
 update_lo_1_value: ipv4.srcip;

 output_value: predicate;
 output_dst: m_meta.srcip_pred;
}

action update_M1_srcip_ac()
{
    update_M1_srcip_bb.execute_stateful_alu_from_hash(hash_1);
}

@pragma stage 0
table update_M1_srcip_t
{
    actions {
        update_M1_srcip_ac;
    }
 default_action: update_M1_srcip_ac;
}

/*---------- rewrite_M1_srcip_t ----------*/
blackbox stateful_alu rewrite_M1_srcip_bb
{
 reg: M1_srcip;
 update_lo_1_value: ipv4.srcip;
}

action rewrite_M1_srcip_ac()
{
    rewrite_M1_srcip_bb.execute_stateful_alu_from_hash(hash_1);
}

@pragma stage 0
table rewrite_M1_srcip_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    nop;
    rewrite_M1_srcip_ac;
  }
 default_action: nop;
}

/*---------- update_M1_dstip_t ----------*/
blackbox stateful_alu update_M1_dstip_bb
{
 reg: M1_dstip;
 condition_lo: register_lo == 0;
 condition_hi: register_lo == ipv4.dstip;

 update_lo_1_predicate: condition_lo or condition_hi;
 update_lo_1_value: ipv4.dstip;

 output_value: predicate;
 output_dst: m_meta.dstip_pred;
}

action update_M1_dstip_ac()
{
    update_M1_dstip_bb.execute_stateful_alu_from_hash(hash_1);
}

@pragma stage 0
table update_M1_dstip_t
{
    actions {
        update_M1_dstip_ac;
    }
 default_action: update_M1_dstip_ac;
}

/*---------- rewrite_M1_dstip_t ----------*/
blackbox stateful_alu rewrite_M1_dstip_bb
{
 reg: M1_dstip;
 update_lo_1_value: ipv4.dstip;
}

action rewrite_M1_dstip_ac()
{
    rewrite_M1_dstip_bb.execute_stateful_alu_from_hash(hash_1);
}

@pragma stage 0
table rewrite_M1_dstip_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    rewrite_M1_dstip_ac;
    nop;
  }
 default_action: nop;
}

/*---------- update_M1_proto_t ----------*/
blackbox stateful_alu update_M1_proto_bb
{
 reg: M1_proto;
 condition_lo: register_lo == 0;
 condition_hi: register_lo == ipv4.proto;

 update_lo_1_predicate: condition_lo or condition_hi;
 update_lo_1_value: ipv4.proto;

 output_value: predicate;
 output_dst: m_meta.proto_pred;
}

action update_M1_proto_ac()
{
    update_M1_proto_bb.execute_stateful_alu_from_hash(hash_1);
}

@pragma stage 0
table update_M1_proto_t
{
  actions {
    update_M1_proto_ac;
  }
 default_action: update_M1_proto_ac;
}

/*---------- rewrite_M1_proto_t ----------*/
blackbox stateful_alu rewrite_M1_proto_bb
{
 reg: M1_proto;
 update_lo_1_value: ipv4.proto;
}

action rewrite_M1_proto_ac()
{
    rewrite_M1_proto_bb.execute_stateful_alu_from_hash(hash_1);
}

@pragma stage 0
table rewrite_M1_proto_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    rewrite_M1_proto_ac;
    nop;
  }
 default_action: nop;
}

/*---------- update_M1_cnt_t ----------*/
blackbox stateful_alu increase_M1_cnt_bb
{
 reg: M1_cnt;
 update_lo_1_value: register_lo + 1;
}

action increase_M1_cnt_ac()
{
    increase_M1_cnt_bb.execute_stateful_alu_from_hash(hash_1);
    modify_field(m_meta.M1_collision, 0);
}

blackbox stateful_alu read_M1_cnt_bb
{
 reg: M1_cnt;
 output_value: register_lo;
 output_dst: m_meta.M1_cnt;
}

action read_M1_cnt_ac()
{
    read_M1_cnt_bb.execute_stateful_alu_from_hash(hash_1);
    modify_field(m_meta.M1_collision, 1);
}

@pragma stage 1
table update_M1_cnt_t
{
    reads {
    m_meta.srcip_pred: exact;
    m_meta.dstip_pred: exact;
    m_meta.proto_pred: exact;
    }
    actions {
      increase_M1_cnt_ac;
      read_M1_cnt_ac;
    }
}

/*---------- rewrite_M1_cnt_t ----------*/
blackbox stateful_alu rewrite_M1_cnt_bb
{
 reg: M1_cnt;
 update_lo_1_value: m_meta.A_cnt;
}

action rewrite_M1_cnt_ac()
{
    rewrite_M1_cnt_bb.execute_stateful_alu_from_hash(hash_1);
}

@pragma stage 1
table rewrite_M1_cnt_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    rewrite_M1_cnt_ac;
    nop;
  }
 default_action: nop;
}

/*---------- update_M2_srcip_t ----------*/
blackbox stateful_alu update_M2_srcip_bb
{
 reg: M2_srcip;
 condition_lo: register_lo == 0;
 condition_hi: register_lo == ipv4.srcip;

 update_lo_1_predicate: condition_lo or condition_hi;
 update_lo_1_value: ipv4.srcip;

 output_value: predicate;
 output_dst: m_meta.srcip_pred;
}

action update_M2_srcip_ac()
{
    update_M2_srcip_bb.execute_stateful_alu_from_hash(hash_2);
}

@pragma stage 2
table update_M2_srcip_t
{
    actions {
        update_M2_srcip_ac;
    }
 default_action: update_M2_srcip_ac;
}

/*---------- rewrite_M2_srcip_t ----------*/
blackbox stateful_alu rewrite_M2_srcip_bb
{
 reg: M2_srcip;
 update_lo_1_value: ipv4.srcip;
}

action rewrite_M2_srcip_ac()
{
    rewrite_M2_srcip_bb.execute_stateful_alu_from_hash(hash_2);
}

@pragma stage 2
table rewrite_M2_srcip_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    rewrite_M2_srcip_ac;
    nop;
  }
 default_action: nop;
}

/*---------- update_M2_dstip_t ----------*/
blackbox stateful_alu update_M2_dstip_bb
{
 reg: M2_dstip;
 condition_lo: register_lo == 0;
 condition_hi: register_lo == ipv4.dstip;

 update_lo_1_predicate: condition_lo or condition_hi;
 update_lo_1_value: ipv4.dstip;

 output_value: predicate;
 output_dst: m_meta.dstip_pred;
}

action update_M2_dstip_ac()
{
    update_M2_dstip_bb.execute_stateful_alu_from_hash(hash_2);
}

@pragma stage 2
table update_M2_dstip_t
{
    actions {
        update_M2_dstip_ac;
    }
 default_action: update_M2_dstip_ac;
}

/*---------- rewrite_M2_dstip_t ----------*/
blackbox stateful_alu rewrite_M2_dstip_bb
{
 reg: M2_dstip;
 update_lo_1_value: ipv4.dstip;
}

action rewrite_M2_dstip_ac()
{
    rewrite_M2_dstip_bb.execute_stateful_alu_from_hash(hash_2);
}

@pragma stage 2
table rewrite_M2_dstip_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    nop;
    rewrite_M2_dstip_ac;
  }
 default_action: nop;
}

/*---------- update_M2_proto_t ----------*/
blackbox stateful_alu update_M2_proto_bb
{
 reg: M2_proto;
 condition_lo: register_lo == 0;
 condition_hi: register_lo == ipv4.proto;

 update_lo_1_predicate: condition_lo or condition_hi;
 update_lo_1_value: ipv4.proto;

 output_value: predicate;
 output_dst: m_meta.proto_pred;
}

action update_M2_proto_ac()
{
    update_M2_proto_bb.execute_stateful_alu_from_hash(hash_2);
}

@pragma stage 2
table update_M2_proto_t
{
    actions {
        update_M2_proto_ac;
    }
    default_action: update_M2_proto_ac;
}

/*---------- rewrite_M2_proto_t ----------*/
blackbox stateful_alu rewrite_M2_proto_bb
{
 reg: M2_proto;
 update_lo_1_value: ipv4.proto;
}

action rewrite_M2_proto_ac()
{
    rewrite_M2_proto_bb.execute_stateful_alu_from_hash(hash_2);
}

@pragma stage 2
table rewrite_M2_proto_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    nop;
    rewrite_M2_proto_ac;
  }
 default_action: nop;
}

/*---------- update_M2_cnt_t ----------*/
blackbox stateful_alu increase_M2_cnt_bb
{
 reg: M2_cnt;
 update_lo_1_value: register_lo + 1;
}

action increase_M2_cnt_ac()
{
    increase_M2_cnt_bb.execute_stateful_alu_from_hash(hash_2);
    modify_field(m_meta.M2_collision, 0);
}

blackbox stateful_alu read_M2_cnt_bb
{
 reg: M2_cnt;

 output_value: register_lo;
 output_dst: m_meta.M2_cnt;
}

action read_M2_cnt_ac()
{
  read_M2_cnt_bb.execute_stateful_alu_from_hash(hash_2);
  modify_field(m_meta.M2_collision, 1);
}

@pragma stage 3
table update_M2_cnt_t
{
    reads {
    m_meta.srcip_pred: exact;
    m_meta.dstip_pred: exact;
    m_meta.proto_pred: exact;
    }
    actions {
      read_M2_cnt_ac;
      increase_M2_cnt_ac;
    }
}

/*---------- rewrite_M2_cnt_t ----------*/
blackbox stateful_alu rewrite_M2_cnt_bb
{
 reg: M2_cnt;
 update_lo_1_value: m_meta.A_cnt;
}

action rewrite_M2_cnt_ac()
{
    rewrite_M2_cnt_bb.execute_stateful_alu_from_hash(hash_2);
}

@pragma stage 3
table rewrite_M2_cnt_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    nop;
    rewrite_M2_cnt_ac;
  }
 default_action: nop;
}

/*---------- update_M3_srcip_t ----------*/
blackbox stateful_alu update_M3_srcip_bb
{
 reg: M3_srcip;
 condition_lo: register_lo == 0;
 condition_hi: register_lo == ipv4.srcip;

 update_lo_1_predicate: condition_lo or condition_hi;
 update_lo_1_value: ipv4.srcip;

 output_value: predicate;
 output_dst: m_meta.srcip_pred;
}

action update_M3_srcip_ac()
{
    update_M3_srcip_bb.execute_stateful_alu_from_hash(hash_3);
}

@pragma stage 4
table update_M3_srcip_t
{
    actions {
        update_M3_srcip_ac;
    }
    default_action: update_M3_srcip_ac;
}

/*---------- rewrite_M3_srcip_t ----------*/
blackbox stateful_alu rewrite_M3_srcip_bb
{
 reg: M3_srcip;
 update_lo_1_value: ipv4.srcip;
}

action rewrite_M3_srcip_ac()
{
    rewrite_M3_srcip_bb.execute_stateful_alu_from_hash(hash_3);
}

@pragma stage 4
table rewrite_M3_srcip_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    nop;
    rewrite_M3_srcip_ac;
  }
 default_action: nop;
}

/*---------- update_M3_dstip_t ----------*/
blackbox stateful_alu update_M3_dstip_bb
{
 reg: M3_dstip;
 condition_lo: register_lo == 0;
 condition_hi: register_lo == ipv4.dstip;

 update_lo_1_predicate: condition_lo or condition_hi;
 update_lo_1_value: ipv4.dstip;

 output_value: predicate;
 output_dst: m_meta.dstip_pred;
}

action update_M3_dstip_ac()
{
    update_M3_dstip_bb.execute_stateful_alu_from_hash(hash_3);
}

@pragma stage 4
table update_M3_dstip_t
{
    actions {
      update_M3_dstip_ac;
    }
    default_action: update_M3_dstip_ac;
}

/*---------- rewrite_M3_dstip_t ----------*/
blackbox stateful_alu rewrite_M3_dstip_bb
{
 reg: M3_dstip;
 update_lo_1_value: ipv4.dstip;
}

action rewrite_M3_dstip_ac()
{
    rewrite_M3_dstip_bb.execute_stateful_alu_from_hash(hash_3);
}

@pragma stage 4
table rewrite_M3_dstip_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    nop;
    rewrite_M3_dstip_ac;
  }
 default_action: nop;
}

/*---------- update_M3_proto_t ----------*/
blackbox stateful_alu update_M3_proto_bb
{
 reg: M3_proto;
 condition_lo: register_lo == 0;
 condition_hi: register_lo == ipv4.proto;

 update_lo_1_predicate: condition_lo or condition_hi;
 update_lo_1_value: ipv4.proto;

 output_value: predicate;
 output_dst: m_meta.proto_pred;
}

action update_M3_proto_ac()
{
    update_M3_proto_bb.execute_stateful_alu_from_hash(hash_3);
}

@pragma stage 4
table update_M3_proto_t
{
    actions {
        update_M3_proto_ac;
    }
    default_action: update_M3_proto_ac;
}

/*---------- rewrite_M3_proto_t ----------*/
blackbox stateful_alu rewrite_M3_proto_bb
{
 reg: M3_proto;
 update_lo_1_value: ipv4.proto;
}

action rewrite_M3_proto_ac()
{
    rewrite_M3_proto_bb.execute_stateful_alu_from_hash(hash_3);
}

@pragma stage 4
table rewrite_M3_proto_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    nop;
    rewrite_M3_proto_ac;
  }
 default_action: nop;
}

/*---------- update_M3_cnt_t ----------*/
blackbox stateful_alu increase_M3_cnt_bb
{
 reg: M3_cnt;
 update_lo_1_value: register_lo + 1;
}

action increase_M3_cnt_ac()
{
    increase_M3_cnt_bb.execute_stateful_alu_from_hash(hash_3);
    modify_field(m_meta.M3_collision, 0);
}

blackbox stateful_alu read_M3_cnt_bb
{
 reg: M3_cnt;

 output_value: register_lo;
 output_dst: m_meta.M3_cnt;
}

action read_M3_cnt_ac()
{
    read_M3_cnt_bb.execute_stateful_alu_from_hash(hash_3);
    modify_field(m_meta.M3_collision, 1);
}

@pragma stage 5
table update_M3_cnt_t
{
    reads {
    m_meta.srcip_pred: exact;
    m_meta.dstip_pred: exact;
    m_meta.proto_pred: exact;
    }
    actions {
      increase_M3_cnt_ac;
      read_M3_cnt_ac;
    }
}

/*---------- rewrite_M3_cnt_t ----------*/
blackbox stateful_alu rewrite_M3_cnt_bb
{
 reg: M3_cnt;
 update_lo_1_value: m_meta.A_cnt;
}

action rewrite_M3_cnt_ac()
{
    rewrite_M3_cnt_bb.execute_stateful_alu_from_hash(hash_3);
}

@pragma stage 5
table rewrite_M3_cnt_t {
  reads {
  m_meta.stage: exact;
  }
  actions {
    nop;
    rewrite_M3_cnt_ac;
  }
 default_action: nop;
}

/*---------- compare_M_cnts_t ----------*/
action compare_M_cnts_ac() {
  subtract(m_meta.flag1, m_meta.M1_cnt, m_meta.M2_cnt);
  subtract(m_meta.flag2, m_meta.M1_cnt, m_meta.M3_cnt);
  subtract(m_meta.flag3, m_meta.M2_cnt, m_meta.M3_cnt);
}

@pragma stage 6
table compare_M_cnts_t {
  actions {
    compare_M_cnts_ac;
  }
 default_action: compare_M_cnts_ac;
}

/*---------- update_A_t ----------*/
blackbox stateful_alu update_A_bb
{
 reg: A;
 condition_lo: register_lo == m_meta.digest;

 update_hi_1_predicate: condition_lo;
 update_hi_1_value: register_hi + 1;

 update_lo_1_predicate: not condition_lo;
 update_lo_1_value: m_meta.digest;

 update_hi_2_predicate: not condition_lo;
 update_hi_2_value: 1;

 output_value: alu_hi;
 output_dst: m_meta.A_cnt;
}

action update_A_ac()
{
    update_A_bb.execute_stateful_alu_from_hash(hash_4);
}

@pragma stage 6
table update_A_t
{
    actions {
      update_A_ac;
    }
    default_action: update_A_ac;
}

/*---------- compare_M_A_cnts_t ----------*/
action M1_cnt_subtract_A_cnt_ac()
{
    subtract(m_meta.flag, m_meta.M1_cnt, m_meta.A_cnt);
    modify_field(m_meta.stage, 1);
}

action M2_cnt_subtract_A_cnt_ac()
{
    subtract(m_meta.flag, m_meta.M2_cnt, m_meta.A_cnt);
    modify_field(m_meta.stage, 2);
}

action M3_cnt_subtract_A_cnt_ac()
{
    subtract(m_meta.flag, m_meta.M3_cnt, m_meta.A_cnt);
    modify_field(m_meta.stage, 3);
}

@pragma stage 7
table compare_M_A_cnts_t
{
    reads {
    m_meta.flag1: ternary;
    m_meta.flag2: ternary;
    m_meta.flag3: ternary;
    }
    actions {
	M1_cnt_subtract_A_cnt_ac;
	M2_cnt_subtract_A_cnt_ac;
	M3_cnt_subtract_A_cnt_ac;
    }
}

/*---------- resubmit_t ----------*/
blackbox stateful_alu count_resubmission_bb
{
 reg: resubmission_counter;
 update_lo_1_value: register_lo + 1;
}

field_list resubmit_fields
{
    m_meta.promotion; //1 bits
    m_meta.stage; //4 bits
    m_meta.A_cnt; //8 bits
}

action resubmit_ac()
{
    modify_field(m_meta.promotion, 1);
    resubmit(resubmit_fields);
    count_resubmission_bb.execute_stateful_alu(0);
}

@pragma stage 8
table resubmit_t
{
    reads {
        m_meta.flag: ternary;
    }
    actions {
        resubmit_ac;//highest bit is 1;
    }
}
/*----------*/

/*++++++++++ counter1_t ++++++++++*/
blackbox stateful_alu counter1_bb
{
 reg: counter1;
 update_lo_1_value: ethernet.etherType;
 /* update_lo_1_value: register_lo + 1; */
}

action counter1_ac()
{
    counter1_bb.execute_stateful_alu(0);
}

table counter1_t {
    actions {
        counter1_ac;
    }
 default_action: counter1_ac;
}
/*----------*/

/*++++++++++ counter2_t ++++++++++*/
blackbox stateful_alu counter2_bb
{
 reg: counter2;
 /* update_lo_1_value: register_lo + 1; */
 update_lo_1_value: vlan_tag.etherType;
}

action counter2_ac()
{
    counter2_bb.execute_stateful_alu(0);
}

table counter2_t {
    actions {
        counter2_ac;
    }
 default_action: counter2_ac;
}
/*----------*/

/*++++++++++ counter3_t ++++++++++*/
blackbox stateful_alu counter3_bb
{
 reg: counter3;
 update_lo_1_value: m_meta.M3_cnt;
}

action counter3_ac()
{
    counter3_bb.execute_stateful_alu(0);
}

table counter3_t {
    actions {
        counter3_ac;
    }
 default_action: counter3_ac;
}
/*----------*/

/*++++++++++ counter4_t ++++++++++*/
blackbox stateful_alu counter4_bb
{
 reg: counter4;
 update_lo_1_value: m_meta.A_cnt;
}

action counter4_ac()
{
    counter4_bb.execute_stateful_alu(0);
}

table counter4_t {
    actions {
        counter4_ac;
    }
 default_action: counter4_ac;
}
/*----------*/

/*++++++++++ counter5_t ++++++++++*/
blackbox stateful_alu counter5_bb
{
 reg: counter5;
 update_lo_1_value: m_meta.digest;
}

action counter5_ac()
{
    counter5_bb.execute_stateful_alu(0);
}

table counter5_t {
    actions {
        counter5_ac;
    }
 default_action: counter5_ac;
}
/*----------*/
